package com.alogic.xscript.plugins;

import com.alogic.xscript.AbstractLogiclet;
import com.alogic.xscript.ExecuteWatcher;
import com.alogic.xscript.Logiclet;
import com.alogic.xscript.LogicletContext;
import com.alogic.xscript.doc.XsObject;
import com.anysoft.util.Properties;
import com.anysoft.util.PropertiesConstants;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *  信息掩码
 *
 * @version 1.6.12.49 [20191108] <br>
 * - 增加mask相关插件，包括身份证，手机，邮箱等; <br>
 */
public class Mask extends AbstractLogiclet {
    protected String id;
    protected String $value;
    protected String mask = "*";

    public Mask(String tag, Logiclet p) {
        super(tag, p);
    }

    public void configure(Properties p){
        super.configure(p);

        id = PropertiesConstants.getString(p,"id","",true);
        $value = PropertiesConstants.getRaw(p,"value","");
        mask = PropertiesConstants.getString(p,"mask","*",true);
    }

    @Override
    protected void onExecute(XsObject root, XsObject current, LogicletContext ctx, ExecuteWatcher watcher) {
        if (StringUtils.isNotEmpty(id)){
            String value = PropertiesConstants.transform(ctx,$value,"");
            if (StringUtils.isEmpty(value)){
                value = PropertiesConstants.getString(ctx,id,"");
            }
            if (StringUtils.isNotEmpty(value)){
                value = mask(value,ctx);
                ctx.SetValue(id,value);
            }
        }
    }

    protected String mask(String value,Properties p) {
        return value;
    }

    /**
     * 正则表达式
     */
    public static class Regex extends Mask{
        protected static final String DEFAULT = "(.*)";
        protected String $regex;

        public Regex(String tag, Logiclet p) {
            super(tag, p);
        }

        public void configure(Properties p){
            super.configure(p);
            $regex = PropertiesConstants.getRaw(p,"regex",$regex);
        }

        @Override
        protected String mask(String value,Properties p) {
            Matcher matcher = Pattern.compile(PropertiesConstants.transform(p,$regex,DEFAULT)).matcher(value);
            if (matcher.find() && matcher.groupCount() == 3){
                StringBuffer buffer = new StringBuffer(matcher.group(1));
                String toMask = matcher.group(2);
                for (int i = 0 ; i < toMask.length() ; i ++){
                    buffer.append(mask);
                }
                buffer.append(matcher.group(3));
                return buffer.toString();
            }
            return value;
        }
    }

    /**
     * 缺省实现
     */
    public static class Default extends Mask{
        protected String begin;
        protected String length;


        public Default(String tag, Logiclet p) {
            super(tag, p);
        }

        public void configure(Properties p){
            super.configure(p);
            begin = PropertiesConstants.getRaw(p,"start", "6");
            length = PropertiesConstants.getRaw(p, "length", "8");
        }

        @Override
        protected String mask(String value,Properties p) {
            int start = getInt(p,begin,6);
            int len = getInt(p,length,8);
            return doMask(value,start,len,mask);
        }

        public static String doMask(String v,int start,int len,String mask){
            start = start < 0 || start > v.length() ? 0 : start;
            len = len > 0 && start + len > v.length()? v.length() - start : len;
            len = len <= 0 ? v.length() - start + len : len;
            len = len <= 0 ? 1 : len;

            char[] buffer = new char[v.length()];

            for (int i = 0;i < buffer.length ; i ++){
                if (i >= start && i < (start + len)){
                    buffer[i] = '*';
                }else{
                    buffer[i] = v.charAt(i);
                }
            }

            return new String(buffer).replaceAll("\\*{1}", mask);
        }

        public int getInt(Properties p, String pattern, int dft){
            String v = p.transform(pattern);
            if (StringUtils.isNotEmpty(v)){
                try {
                    return Integer.parseInt(v);
                }catch (NumberFormatException ex){
                    return dft;
                }
            }
            return dft;
        }
    }

    /**
     * 居民身份证mask
     */
    public static class IdCardMask extends Mask{
        protected Pattern pattern = Pattern.compile("(.{8})(.{6})(.*)");
        public IdCardMask(String tag, Logiclet p) {
            super(tag, p);
        }
        @Override
        protected String mask(String value,Properties p) {
            Matcher matcher = pattern.matcher(value);
            if (matcher.find()){
                StringBuffer buffer = new StringBuffer(matcher.group(1));
                String toMask = matcher.group(2);
                for (int i = 0 ; i < toMask.length() ; i ++){
                    buffer.append(mask);
                }
                buffer.append(matcher.group(3));
                return buffer.toString();
            }
            return value;
        }
    }

    /**
     * mobile
     */
    public static class MobileMask extends Mask{
        protected Pattern pattern = Pattern.compile("(.*)(.{4})(.{4})");
        public MobileMask(String tag, Logiclet p) {
            super(tag, p);
        }

        @Override
        protected String mask(String value,Properties p) {
            Matcher matcher = pattern.matcher(value);
            if (matcher.find()){
                StringBuffer buffer = new StringBuffer(matcher.group(1));
                String toMask = matcher.group(2);
                for (int i = 0 ; i < toMask.length() ; i ++){
                    buffer.append(mask);
                }
                buffer.append(matcher.group(3));
                return buffer.toString();
            }
            return value;
        }
    }

    /**
     * email
     */
    public static class EmailMask extends Mask{
        protected Pattern pattern = Pattern.compile("(.{1})(.{0,4})(.*)(@.*)");
        public EmailMask(String tag, Logiclet p) {
            super(tag, p);
        }

        @Override
        protected String mask(String value,Properties p) {
            Matcher matcher = pattern.matcher(value);
            if (matcher.find()){
                StringBuffer buffer = new StringBuffer(matcher.group(1));
                String toMask = matcher.group(2);
                for (int i = 0 ; i < toMask.length() ; i ++){
                    buffer.append(mask);
                }
                buffer.append(matcher.group(3));
                buffer.append(matcher.group(4));
                return buffer.toString();
            }
            return value;
        }
    }
}
